import TopMenuView from '../common/TopMenuView';
import QuickTool from '../base/Tool/QuickTool';
import { Game06_CreateInfo, Game06_Group } from './Game06_Data';
import { DirectionDefine } from '../base/Tool/ScreenTool';
import Game06_Data from './Game06_Data';
import CounterDown from '../common/CounterDown';
import GameOverView from '../common/GameOverView';
import Game06_Card from './Game06_Card';
import CfgMgr from '../base/Config/CfgMgr';
import GameEntry from '../GameEntry';
import GameBase from '../common/GameBase';
import { SaveData06 } from '../common/SaveData';
import SaveData from '../common/SaveData';
import RookieBottom from '../common/RookieBottom';
import SoundMgr from '../base/Sound/SoundMgr';
// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class Game06 extends GameBase {

    @property(cc.Prefab)
    topViewPrefab: cc.Prefab = null;
    topView: TopMenuView = null;

    @property(cc.Prefab)
    gameOverPrefab: cc.Prefab = null;
    gameOverView: GameOverView = null;

    @property(cc.Node)
    bgMoveNode: cc.Node = null;

    @property(cc.Prefab)
    cardPrefab: cc.Prefab = null;

    @property(cc.Node)
    tempTargetNode: cc.Node = null;

    @property(cc.Node)
    targetNode: cc.Node = null;

    @property(CounterDown)
    countDown: CounterDown = null;

    @property(RookieBottom)
    myRookie: RookieBottom = null;

    @property([cc.SpriteFrame])
    suitsSpriteFrame = new Array<cc.SpriteFrame>();

    @property(cc.Node)
    shouzhiNode: cc.Node = null;

    createInfos = new Array<Game06_CreateInfo>();

    data: Game06_Data = null;

    pools = new Array<Game06_Card>();
    cards = new Array<Game06_Card>();
    tagCard: Game06_Card = null;
    gameing = false;
    errorCount = 0;
    direction = DirectionDefine.right

    saveData: SaveData06 = null;
    allOK = 0

    rookieCard: Game06_Card = null;

    @property(cc.Node)
    rClickNode: cc.Node = null;
    rookiePause = false;

    getLevelData (level) {
        let data = new Game06_Data()
        if (level ==0){
            data.createGroup()
            return data
        } 

        let config = CfgMgr.Instance.game06Cfgs.TryGetValue(level)
        
        data.countdown = config.countdown
        data.tipsDealy = config.tipsDealy
        data.targetRate = config.targetRate
        data.speed = config.speed
        data.canMissRate = config.canMissRate
        data.canErrorCount = config.canErrorCount
        data.timeLimit = config.timeLimit

        data.createGroup()
        return data
    }

    start () {
         this.syncLevel()

        this.topView = cc.instantiate(this.topViewPrefab).getComponent(TopMenuView).hideBottom()
        this.topView.node.parent = this.node

        let node = cc.instantiate(this.gameOverPrefab)
        node.parent = this.node
        node.active = false
        this.gameOverView = node.getComponent(GameOverView)
        this.gameOverView.clickFn = () => {
            this.gameOverView.dismiss()
            this.gameStart(this.getLevelData(this.currentLevel))
        }

        if (this.rookie) {
            SaveData.startCall(()=>{
                this.initRookie()
            })
        }else{
            this.gameStart(this.getLevelData(this.currentLevel))
        }

        this.node.on(cc.Node.EventType.TOUCH_START, this.touchStart, this)
    }

    clearGame () {
        this.gameing = false
        this.allOK = 0
        this.errorCount = 0;
        if (this.cards.length > 0) {
            this.cards.forEach(element => {
                this.retCard(element)
            });
            this.cards.splice(0, this.cards.length)
        }
        this.createInfos.splice(0, this.createInfos.length)
        this.tagCard = null
    }

    touchStart (touch: cc.Event.EventTouch) {
        if (!this.gameing) return
        let ts = touch.getTouches()
        
        ts.forEach(e=>{
            let p = e._point
            let t = this.node.parent.convertToWorldSpaceAR(p)
            
            this.cards.forEach(card => {
                if (card.node.getBoundingBoxToWorld().contains(t)) {
                    // console.log(card);
                    
                    if (card.ok && !card.use) {
                        card.doUse()
                        if (this.saveData) this.saveData.lvCorrectCount ++
                    }else if (!card.ok) {
                        if (++ this.errorCount > this.data.canErrorCount) {
                            if (this.saveData != null) {
                                this.saveData.lvDismissCount = this.allOK - this.saveData.lvCorrectCount
                                this.saveData.reactionRate = this.saveData.lvCorrectCount / this.data.timeLimit
                                this.saveData.useTime = this.topView.useTime
                                SaveData.overUpload(6, false, this.saveData, (data)=>{
                                    if (data.level) {
                                        this.clearGame()
                                        this.currentLevel = data.level
                                        this.gameStart(this.getLevelData(this.currentLevel))
                                    }
                                })
                            }

                            this.gameOver("错误次数过多")
                        }
                    }
                }
            });
        })
    }

    gameStart (data: Game06_Data) {
        this.saveData = new SaveData06(this.currentLevel)

        SaveData.startCall(()=>{
            this.clearGame()

            this.data = data
            //this.topView.titleLabel.string = `七彩扑克牌LV.${this.currentLevel}`
            this.topView.titleLabel.string = `抓紧时间`
    
            let d = DirectionDefine.random()
    
            for (let i=0;i<4;i++) {
                this.createInfos.push(Game06_CreateInfo.createOne(i, d))
            }
    
            this.direction = d
    
            this.createInfos.forEach(info=>{
               for (let i=0;i<5;i++) {
                    let card = this.getCard()
                    card.node.parent = this.bgMoveNode
                    card.node.width = info.w
                    card.node.height = info.h
    
                    card.node.setPosition(info.getPosition(i))
                    this.cards.push(card)
    
                    if (i == 0 && this.tagCard == null) this.tagCard = card
               }
            })
    
            this.countDown.startGameTimer(this.data.countdown, ()=>{
                this.showTarget()
            })
    
            this.topView.startRightTime(this.data.timeLimit, ()=>{
                if (this.saveData != null) {
                    this.saveData.lvDismissCount = this.allOK - this.saveData.lvCorrectCount
                    this.saveData.reactionRate = this.saveData.lvCorrectCount / this.data.timeLimit
                    this.saveData.useTime = this.topView.useTime
                    SaveData.overUpload(6, true, this.saveData, (data)=>{
                        if (data.level) {
                            this.clearGame()
                            this.currentLevel = data.level
                            this.gameStart(this.getLevelData(this.currentLevel))
                        }
                    })
                }
    
                this.gameOver("时间到!!")
            })
            this.topView.pauseRightTime()
        })
    }

    initRookie () {
        this.clearGame()
        this.data = this.getLevelData(0)
        this.topView.titleLabel.string = `七彩扑克牌-教学关卡`

        this.direction = DirectionDefine.right

        for (let i=0;i<4;i++) {
            this.createInfos.push(Game06_CreateInfo.createOne(i, this.direction))
        }

        this.createInfos.forEach(info=>{
            for (let i=0;i<5;i++) {
                 let card = this.getCard()
                 card.node.parent = this.bgMoveNode
                 card.node.width = info.w
                 card.node.height = info.h
 
                 card.node.setPosition(info.getPosition(i))
                 this.cards.push(card)
 
                 if (i == 0 && this.tagCard == null) this.tagCard = card
            }
        })

        this.updateTargetView(this.tempTargetNode, this.data.targetGroup)
        this.tempTargetNode.active = true
        this.tempTargetNode.opacity = 255

        this.myRookie.node.active = true
        this.myRookie.titles = ["请记住屏幕中对目标卡牌的描述",
        "请点击与之前描述一致的卡牌",
        "真棒，你已成功完成卡牌大师项目的新手教学啦~~马上正式开始吧~"]
        this.myRookie.titleLabel.string = this.myRookie.titles[0]
        SoundMgr.Instance.playScriptSound(0)

        this.myRookie.again = () => {
            this.clearGame()
            this.rookiePause = false
            this.myRookie.replay()
            this.initRookie()
        }

        this.myRookie.over = () => {
            this.shouzhiNode.active = false
            SoundMgr.Instance.stop()
            SaveData.endGuide(level=>{
                this.currentLevel = level
                this.myRookie.node.active = false
                this.rookie = false
                this.tempTargetNode.active = false
                this.gameStart(this.getLevelData(this.currentLevel))
            })
        }

        this.myRookie.next = (step: number) => {
            this.myRookie.titleLabel.string = this.myRookie.titles[step]
            SoundMgr.Instance.playScriptSound(step)
            if (step == 1) {
                this.tempTargetNode.runAction(cc.fadeOut(0.5))
                this.realStart()
                this.myRookie.next_valid(false)
            }else if (step == 2) {
                this.shouzhiNode.active = false
                this.myRookie.readyOver()
            }
        }
    }

    showTarget () {
        this.updateTargetView(this.tempTargetNode, this.data.targetGroup)
        this.tempTargetNode.active = true
        this.tempTargetNode.opacity = 255

        this.scheduleOnce(()=>{
            this.tempTargetNode.runAction(cc.fadeOut(0.5))
            this.updateTargetView(this.targetNode, this.data.targetGroup)
            this.targetNode.opacity = 0
            this.targetNode.active = true
            this.targetNode.runAction(cc.fadeIn(0.5))
            this.realStart()
        }, this.data.tipsDealy)
    }

    realStart () {
        this.topView.startRightTime()

        // this.createOnceGroup()
        this.gameing = true
    }

    gameOver (str) {
        this.topView.pauseRightTime()
        this.gameOverView.show(str)
        this.gameing = false
        this.targetNode.active = false
    }

    update (dt) {
        if (this.gameing && !this.rookiePause) {
            for (let i=this.cards.length-1;i>=0;i--) {
                let card = this.cards[i]
                //1秒走this.data.speed
                //60zheng
                if (this.direction == DirectionDefine.right) {
                    card.node.x += this.data.speed *QuickTool.winsc.width * dt

                    if (card.node.x >= QuickTool.winsc.width/2 + 400) {
                        this.retCard(card)
                        this.cards.splice(i, 1)
                    }
                }else if (this.direction == DirectionDefine.left) {
                    card.node.x -= this.data.speed *QuickTool.winsc.width * dt

                    if (card.node.x <= -QuickTool.winsc.width/2 - 400) {
                        this.retCard(card)
                        this.cards.splice(i, 1)
                    }
                }else if (this.direction == DirectionDefine.top) {
                    card.node.y += this.data.speed *QuickTool.winsc.height * dt

                    if (card.node.y >= QuickTool.winsc.height/2 + 400) {
                        this.retCard(card)
                        this.cards.splice(i, 1)
                    }
                }else if (this.direction == DirectionDefine.bottom) {
                    card.node.y -= this.data.speed *QuickTool.winsc.height * dt

                    if (card.node.y <= -QuickTool.winsc.height/2 - 400) {
                        this.retCard(card)
                        this.cards.splice(i, 1)
                    }
                }
            }
                

            if (this.direction == DirectionDefine.right) {
                if (this.tagCard.node.x >= this.createInfos[0].getPosition(1).x) {
                    this.createOnceGroup()
                }
            }else if (this.direction == DirectionDefine.left) {
                if (this.tagCard.node.x <= this.createInfos[0].getPosition(1).x) {
                    this.createOnceGroup()
                }
            }else if (this.direction == DirectionDefine.top) {
                if (this.tagCard.node.y >= this.createInfos[0].getPosition(1).y) {
                    this.createOnceGroup()
                }
            }else if (this.direction == DirectionDefine.bottom) {
                if (this.tagCard.node.y <= this.createInfos[0].getPosition(1).y) {
                    this.createOnceGroup()
                }
            }
           
            if (this.rookie && this.rookieCard) {
                if (this.rookieCard.node.x > this.createInfos[0].getPosition(2).x) {
                    this.rClickNode.active = true
                    let ncard = this.rookieCard
                    
                    let card = this.getCard()
                    card.node.width = this.rookieCard.node.width
                    card.node.height = this.rookieCard.node.height
                    card.node.setPosition(this.rookieCard.node.getPosition())
                    card.set(this.rookieCard._g, this.rookieCard._p, this.rookieCard._f)
                    card.node.parent = this.rClickNode
                    card.cellNode.active = true
                    this.rookiePause = true
                    this.rookieCard = null

                    let call = () => {
                        card.node.off(cc.Node.EventType.TOUCH_END, call)
                        this.retCard(card)
                        this.rClickNode.active = false
                        ncard.doUse()
                        this.myRookie.onClickNext()
                    }

                    card.node.on (cc.Node.EventType.TOUCH_END, call)

                    this.shouzhiNode.setPosition(this.shouzhiNode.parent.convertToNodeSpaceAR(card.node.convertToWorldSpaceAR(cc.v2(0,0))))
                    this.shouzhiNode.active = true
                }
            }
        }
    }

    createOnceGroup () {
        for (let i=0;i<this.createInfos.length;i++) {
            let info = this.createInfos[i]

            let card = this.getCard()
            card.node.parent = this.bgMoveNode
            card.node.width = info.w
            card.node.height = info.h

            card.node.setPosition(info.getPosition(0))
            this.cards.push(card)

            let r = QuickTool.randomNum(0, 1000)
            if (r > 400) {
                this.cardPro(card)
            }

            if (i == 0) {
                this.tagCard = card
            }
        }
    }

    cardPro (card: Game06_Card) {
        if (this.allOK == 0 && this.rookie) {
            card.set(this.data.targetGroup, this.randomOtherColor(this.data.targetGroup), this.suitsSpriteFrame)
            card.ok = true
            this.allOK ++
            this.rookieCard = card
            return
        }

        let rate = this.data.targetRate * 100
        let r = QuickTool.randomNum(0,100)

        if (r <= rate) { //target
            card.set(this.data.targetGroup, this.randomOtherColor(this.data.targetGroup), this.suitsSpriteFrame)
            card.ok = true
            this.allOK ++
        }else{
            let g = this.data.disturbGroups[QuickTool.randomNum(0, this.data.disturbGroups.length-1)]
            card.set(g, this.randomOtherColor(g), this.suitsSpriteFrame)
            card.ok = false
        }
    }

    randomOtherColor (g: Game06_Group) {
        let gs = g.color

        while (gs == g.color) {
            gs = this.data.useColors[QuickTool.randomNum(0, this.data.useColors.length-1)]
        }

        return gs
    }

    //
    updateTargetView (node: cc.Node, targetGroup: Game06_Group) {
        node.getChildByName("point").getComponent(cc.Label).string = targetGroup.point
        node.getChildByName("suits").getComponent(cc.Sprite).spriteFrame = this.suitsSpriteFrame[targetGroup.suits]

        // node.getChildByName("point").color = targetGroup.color.color
        // node.getChildByName("suits").color = targetGroup.color.color
        node.getChildByName("color").color = targetGroup.color.color

        node.getChildByName("colorLabel").getComponent(cc.Label).string = `底色：${targetGroup.color.name}`
    }

    getCard () {
        if (this.pools.length == 0) {
            this.pools.push(cc.instantiate(this.cardPrefab).getComponent(Game06_Card))
        }

        let card = this.pools.pop()
        card.node.active = true
        return card;
    }

    retCard (card: Game06_Card) {
        card.node.active = false
        card.reset()
        this.pools.push(card)
    }
}

/**
 * public void NOSomethingA()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingB()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingC()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingD()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingE()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingF()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingG()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingH()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingI()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingJ()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingK()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingL()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingM()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingN()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingO()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingP()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingQ()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingR()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingS()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingT()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingU()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingV()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
 */

/**
 * public void NOSomethingA()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingB()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingC()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingD()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingE()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingF()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingG()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingH()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingI()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingJ()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingK()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingL()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingM()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingN()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingO()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingP()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingQ()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingR()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingS()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingT()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingU()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
public void NOSomethingV()
{
    string name = "NoName";
    string first = "what monther's is who?011245";
}
 */
